package client

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"gin-epg/internal/app/dao"
	"gin-epg/internal/app/entity"
	"net/url"
	"strings"
	"time"

	"github.com/go-resty/resty/v2"
	"github.com/spf13/cast"
)

// 四川有线 频道名称映射
var mapSc96655 = map[string]string{
	"3943_1": "重温经典",
	"3432_2": "梨园",
	"3957_2": "中国交通",
	"3418_2": "CHC影迷电影",
	"3419_2": "CHC家庭影院",
	"3416_2": "CHC动作电影",
	// 更多键值对...
}

/*
 * 频道列表获取
 * curl --location 'http://epg.iqy.sc96655.com/v1/getChannels?partner=1&terminal=&definition=&citycode=&adcode=&charge_type=&channel_type=' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI5ODQwODlhNjc1OGU0ZjJlOTViMjk4NWM4YjA1MDNmYiIsImNvbXBhbnkiOiJxaXlpIiwibmFtZSI6InRlcm1pbmFsIn0.1gDPpBcHJIE8dLiq7UekUlPWMtJOYymI8zoIYlsVgc4'
 * curl --location 'http://epg.iqy.sc96655.com/v1/getChannels?partner=2&terminal=&definition=&citycode=&adcode=&charge_type=&channel_type=' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI5ODQwODlhNjc1OGU0ZjJlOTViMjk4NWM4YjA1MDNmYiIsImNvbXBhbnkiOiJxaXlpIiwibmFtZSI6InRlcm1pbmFsIn0.1gDPpBcHJIE8dLiq7UekUlPWMtJOYymI8zoIYlsVgc4'
 * partner=1时有重温经典 partner=2没有重温经典
*/

// HandleSc96655Cron 处理四川有线节目单
func HandleSc96655Cron(beforeDay, afterDay int) error {
	dao.Logger.Infof("handleSc96655Cron start")
	source := "sc96655"

	client := resty.New()
	for key, value := range mapSc96655 {
		dao.Logger.Infof("Key: %s, Value: %s", key, value)

		// 分割 key 为 channel 和 partner
		parts := strings.Split(key, "_")
		if len(parts) < 2 {
			dao.Logger.Errorf("Invalid key format: %s", key)
			continue
		}
		channel := parts[0]
		partner := parts[1]

		for dayOffset := -beforeDay; dayOffset <= afterDay; dayOffset++ {
			date := time.Now().AddDate(0, 0, dayOffset).Format("2006-01-02")
			dao.Logger.Infof(date)

			// 构建URL参数
			params := url.Values{}
			params.Add("channel", channel)
			params.Add("begin_time", date+" 00:00:00")
			params.Add("end_time", date+" 23:59:59")
			params.Add("partner", partner)
			// 编码参数
			encodedParams := params.Encode()

			url := fmt.Sprintf("http://epg.iqy.sc96655.com/v1/getPrograms?%s", encodedParams)
			// 打印url
			dao.Logger.Infof("url: %s", url)
			resp, err := client.R().
				SetHeaders(map[string]string{
					"Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI5ODQwODlhNjc1OGU0ZjJlOTViMjk4NWM4YjA1MDNmYiIsImNvbXBhbnkiOiJxaXlpIiwibmFtZSI6InRlcm1pbmFsIn0.1gDPpBcHJIE8dLiq7UekUlPWMtJOYymI8zoIYlsVgc4",
					"User-Agent":    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
				}).
				Get(url)

			if err != nil {
				return fmt.Errorf("failed to get data from URL: %v", err)
			}
			// 打印响应body
			dao.Logger.Debugf("Response Body: %s", string(resp.Body()))

			var data map[string]interface{}
			if err := json.Unmarshal(resp.Body(), &data); err != nil {
				return fmt.Errorf("failed to unmarshal JSON: %v", err)
			}

			if retData, ok := data["ret_data"].([]interface{}); ok {
				// 获取当前日期范围内的已有节目记录
				db := dao.SqlSession
				dateParsed, _ := time.Parse("2006-01-02", date)
				var existingRecords []entity.EpgProgramCollect
				if err := db.Where(&entity.EpgProgramCollect{Channel: value, Date: entity.NullDate{sql.NullTime{Time: dateParsed, Valid: true}}, Source: source}).Find(&existingRecords).Error; err != nil {
					dao.Logger.Errorf("failed to get existing records: %v", err)
					continue
				}

				existingMap := make(map[string]*entity.EpgProgramCollect)
				for i := range existingRecords {
					existingMap[existingRecords[i].Start] = &existingRecords[i]
				}

				var newPrograms, updatePrograms, deletePrograms []entity.EpgProgramCollect

				for _, program := range retData {
					programMap := program.(map[string]interface{})
					startDate := cast.ToString(programMap["begin_time"])
					momentStartDate, _ := time.Parse("2006-01-02 15:04:05", startDate)
					stopDate := cast.ToString(programMap["end_time"])
					momentStopDate, _ := time.Parse("2006-01-02 15:04:05", stopDate)

					channel := value
					date := momentStartDate.Format("2006-01-02")
					start := momentStartDate.Format("15:04")
					stop := momentStopDate.Format("15:04")

					if channel != "" && date != "" && start != "" && stop != "" {
						title := cast.ToString(programMap["name"])
						desc := cast.ToString(programMap["desc"])

						if existingRecord, ok := existingMap[start]; ok {
							if existingRecord.Title != title || existingRecord.End != stop {
								existingRecord.Title = title
								existingRecord.Desc = desc
								existingRecord.End = stop
								existingRecord.UpdateTime = entity.NullTime{sql.NullTime{Time: time.Now(), Valid: true}}
								updatePrograms = append(updatePrograms, *existingRecord)
							}
							delete(existingMap, start)
						} else {
							newRecord := entity.EpgProgramCollect{
								Title:      title,
								Desc:       desc,
								Source:     source,
								Channel:    channel,
								Date:       entity.NullDate{sql.NullTime{Time: dateParsed, Valid: true}},
								Start:      start,
								End:        stop,
								CreateTime: entity.NullTime{sql.NullTime{Time: time.Now(), Valid: true}},
							}
							newPrograms = append(newPrograms, newRecord)
						}
					}
				}

				// 处理需要删除的记录
				for _, record := range existingMap {
					deletePrograms = append(deletePrograms, *record)
				}

				// 执行数据库操作
				if len(updatePrograms) > 0 {
					for _, program := range updatePrograms {
						if err := db.Model(&program).Updates(entity.EpgProgramCollect{Title: program.Title, Desc: program.Desc, End: program.End, UpdateTime: program.UpdateTime}).Error; err != nil {
							dao.Logger.Errorf("update error: %v", err)
						} else {
							dao.Logger.Debugf("update success: %v", program)
						}
					}
				}

				if len(newPrograms) > 0 {
					for _, program := range newPrograms {
						if err := db.Create(&program).Error; err != nil {
							dao.Logger.Errorf("insert error: %v", err)
						} else {
							dao.Logger.Debugf("insert success: %v", program)
						}
					}
				}

				if len(deletePrograms) > 0 {
					for _, program := range deletePrograms {
						if err := db.Delete(&program).Error; err != nil {
							dao.Logger.Errorf("delete error: %v", err)
						} else {
							dao.Logger.Debugf("delete success: %v", program)
						}
					}
				}
			}
		}
	}
	return nil
}
